package pathways.marvin_test;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Vector;

import pathways.CPathway;
import pathways.CReaction;
import pathways.CSubstrate;
import pathways.Database.Implementation.CDatabase;
import pathways.util.Debug.CDebug;

/**
 * Title:
 * Description:
 * Copyright:    Copyright (c) 2001
 * Company:
 * @author Jia An Chen
 * @version 1.0
 */

public class CAtomTraceDatabase implements IAtomTraceDatabase {
  private static CAtomTraceDatabase theDatabase = null;
  private CDatabase db;
  
  private CAtomTraceDatabase(CDatabase database) 
  {
    db = database;
  }

  static public CAtomTraceDatabase create(CDatabase database) {
    if (theDatabase == null) {
      theDatabase = new CAtomTraceDatabase(database);
    }
    return theDatabase;
  }

  // returns a vector of CTraceMolecules
  // VJ???
  public Vector getAtomTraces(CPathway pathway, CSubstrate substrate, int atomNum) 
  {    
    Vector traces = new Vector();
    Vector alreadyTracedSubs = new Vector();
    
    traces.add(new CTraceMolecule(substrate.getID(),atomNum));
    
    getTrace(substrate,atomNum,traces,alreadyTracedSubs);
    
    return traces;
  }

  //
  // VJ???
  public boolean updateAtomTrace(long rxnID, Vector traceIDPath) {
    
    CTraceIDPath idPath = null;
    
    db.getUpdate().deleteTraces(rxnID);
    
    for (int i = 0; i < traceIDPath.size(); i++) {
      idPath = (CTraceIDPath)traceIDPath.get(i);
      
      if (!db.getUpdate().newTrace(rxnID,idPath.substrateID,idPath.productID,idPath.from,idPath.to))
      {
        CDebug.println(this, "updateAtomTrace() Entry of trace for rxnID = " + rxnID + " failed.");
        return false; 
      }  
    }
    
    return true;
  }

  // VJ???
  public ResultSet getAtomTraces(CReaction rxn) 
  {
    return db.getSelect().getTraces(rxn.getID());
  }
  
  private void getTrace(CSubstrate s, int from, Vector traces, Vector alreadyTracedSubs)
  {
    if (alreadyTracedSubs.contains(s))
       return;
    else
       alreadyTracedSubs.add(s);
        
    CTraceIDPath trace;
    CReaction r;
    
    for (int i = 0; i < 4; i++)
    {
      r = s.getConnectionPoint(i).getAttachedReaction();
      
      if (r != null)
      {
         trace = getTrace(r,from);
         if (trace != null)
         {
          traces.add(new CTraceMolecule(r.getProduct().getID(),trace.to));
          getTrace(r.getProduct(),trace.to,traces,alreadyTracedSubs);
         }
      }
    }  
  }
  
  private CTraceIDPath getTrace(CReaction rxn, int from)
  {
    ResultSet r = db.getSelect().getTrace(rxn.getID(),rxn.getSubstrate().getID(),rxn.getProduct().getID(),from);
    
    try {
      if (r.next())
      {
        return (new CTraceIDPath(rxn.getSubstrate().getID(),from,rxn.getProduct().getID(),r.getInt(1)));  
      }
    } catch(SQLException e) {
      CDebug.println(this,"getTrace(rxn,from) Exception: " + e.toString()); 
    }
    
    return null; 
  }  
}

